/*******************************************************************************
 * Copyright (c) 2001, 2002 Boris Pruessmann and others. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Common Public License v0.5 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors: Boris Pruessmann - Initial implementation.
 ******************************************************************************/
package net.sourceforge.perforce.ui.action;

import com.google.common.collect.Lists;

import net.sourceforge.perforce.core.PerforceCorePlugin;
import net.sourceforge.perforce.core.PerforceException;
import net.sourceforge.perforce.core.api.IPerforceServer;
import net.sourceforge.perforce.ui.dialogs.ChangeSpecDialog;
import net.sourceforge.perforce.ui.internal.Policy;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.IAction;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;

import java.util.Iterator;
import java.util.List;

/**
 * @version $Revision: 488 $
 * @author <a href="mailto:bpruessmann@users.sourceforge.net">Boris
 *         Pruessmann</a>
 */
public class NewChangelistAction extends PerforceAction implements IViewActionDelegate {
  //----------------------------------------------------------------------------
  // -- Public Methods

  @Override
  public void run(IAction action) {
    final PerforceException[] exception = {null};

    Display display = getShell().getDisplay();
    display.syncExec(new Runnable() {
      public void run() {
        IPerforceServer[] servers = getSelectedServers();
        Policy.assertTrue(servers.length == 1);

        try {
          ChangeSpecDialog dialog = ChangeSpecDialog.newInstance(getShell(), servers[0]);
          if (dialog.open() == ChangeSpecDialog.OK) {
            servers[0].change(dialog.getChangeSpec());
            PerforceCorePlugin.getPlugin().broadcastChangelistStateChanges(servers);
          }
        } catch (PerforceException e) {
          exception[0] = e;
        }
      }
    });

    if (exception[0] != null) {
      handle(exception[0]);
    }
  }

  public void init(IViewPart view) {
  }

  // ---------------------------------------------------------------------------
  // Protected Methods

  @SuppressWarnings("unused")
  // PerforceException
  @Override
  protected boolean isEnabled() throws PerforceException {
    IPerforceServer[] servers = getSelectedServers();
    if (servers.length == 1) {
      return true;
    }

    return false;
  }

  //----------------------------------------------------------------------------
  // - Private Methods

  /**
   * Call this method to retrieve an array of selected servers.
   * 
   * @return array of selected servers.
   */
  private IPerforceServer[] getSelectedServers() {
    List<IPerforceServer> resources = null;
    if (!getSelection().isEmpty()) {
      resources = Lists.newArrayList();
      for (Iterator<?> elements = getSelection().iterator(); elements.hasNext();) {
        Object next = elements.next();
        if (next instanceof IPerforceServer) {
          resources.add((IPerforceServer) next);
          continue;
        } else if (next instanceof IAdaptable) {
          IAdaptable a = (IAdaptable) next;
          Object adapter = a.getAdapter(IPerforceServer.class);
          if (adapter instanceof IPerforceServer) {
            resources.add((IPerforceServer) adapter);
            continue;
          }
        }
      }
    }

    if (resources != null && !resources.isEmpty()) {
      return resources.toArray(new IPerforceServer[resources.size()]);
    }

    return new IPerforceServer[0];
  }
}
